package com.ruoyi.common.utils;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.util.IoUtils;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * <p>
 *  文件生成
 * </p>
 *
 * @author liyi
 * @since 2024/12/25 16:26
 */
public class FileUploadUtils {

    /**
     * 从Excel输入流读取数据到 list
     *
     * @param inputStream  excel输入流
     * @param cellKeys
     * @param fieldMapping
     * @return
     */
    public List<Map<String, Object>> readExcelByInputStream(InputStream inputStream, String[] cellKeys, Map<String, String> fieldMapping) {
        List<Map<String, Object>> dataList = new ArrayList<>();
        List<Object> list = EasyExcelFactory.read(inputStream, new Sheet(1));
        String listString = JSONObject.toJSONString(list);
        JSONArray arrayList = JSONArray.parseArray(listString);
        String[] newCellKeys = this.columnOrderByExcelHeader(arrayList, cellKeys, fieldMapping);

        for (int i = 0; i < arrayList.size(); i++) {
            JSONArray rowData = JSONArray.parseArray(JSONObject.toJSONString(arrayList.get(i)));
            Map<String, Object> cellMap = new HashMap<>();

            for (int j = 0; j < newCellKeys.length; j++) {
                String cellKey = newCellKeys[j];
                if (rowData.size() > j) {
                    cellMap.put(cellKey, this.removeSpace(rowData.get(j)));
                }
            }

            cellMap.put("row_num", i + 1);
            dataList.add(cellMap);
        }
        return dataList;
    }

    private Object removeSpace(Object o) {
        if (o != null) {
            return o.toString().trim();
        }
        return null;
    }


    public String[] columnOrderByExcelHeader(JSONArray arrayList, String[] cellKeys, Map<String, String> fieldMapping) {
        String[] newCellKeys = new String[cellKeys.length];
        List<String> headerList = (List<String>) arrayList.get(1);
        if (headerList != null && headerList.size() == cellKeys.length) {
            for (int i = 0; i < headerList.size(); i++) {
                newCellKeys[i] = fieldMapping.get(headerList.get(i));
            }
            return newCellKeys;
        } else {
            throw new RuntimeException("模板不正确，请确认模板");
        }
    }

    /**
     * 构建Excel文档，并上传
     *
     * @param filename
     * @param columnIds
     * @param columnNames
     * @param datas
     * @return
     */
    public String uploadExcelByInputStream(String filename, String[] columnIds, String[] columnNames, List<Map<String, Object>> datas) {

        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet(filename);
        sheet.setDefaultColumnWidth(15);
        XSSFCellStyle style = workbook.createCellStyle();

        XSSFFont font = workbook.createFont();
        style.setFont(font);

        //表头
        XSSFRow rowTitle = sheet.createRow(0);
        for (int index = 0; index < columnNames.length; index++) {
            XSSFCell cell = rowTitle.createCell(index);
            cell.setCellStyle(style);
            XSSFRichTextString text = new XSSFRichTextString(columnNames[index]);
            cell.setCellValue(text);
        }

        //表数据
        for (int index = 0; index < datas.size(); index++) {
            Map<String, Object> map = datas.get(index);
            XSSFRow row = sheet.createRow(index + 1);
            this.setCellValue(columnIds, map, row);
        }

        ByteArrayOutputStream os = new ByteArrayOutputStream();

        try {
            workbook.write(os);
            byte[] content = os.toByteArray();

            //总要文件系项
            DiskFileItem fileItem = (DiskFileItem) new DiskFileItemFactory().createItem("file", "*/*", true, filename);

            ByteArrayInputStream input = new ByteArrayInputStream(content);

            OutputStream output = fileItem.getOutputStream();

            IoUtils.copy(input, output);

            CommonsMultipartFile file = new CommonsMultipartFile(fileItem);
            //todo 上传 file

        } catch (IOException e) {
            e.printStackTrace();
        }


        return null;
    }

    private void setCellValue(String[] columnIds, Map<String, Object> map, XSSFRow row) {
        for (int i = 0; i < columnIds.length; i++) {
            Object value = map.get(columnIds[i]);
            XSSFCell cell = row.createCell(i);
            cell.getCellStyle().setWrapText(true);
            String textValue = null;
            if (value != null && value instanceof Date) {
                Date date = (Date) value;
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                textValue = sdf.format(date);
            }

            if (value != null && !(value instanceof Date)) {
                textValue = value.toString();
            }

            if (textValue != null) {
                XSSFRichTextString ri = new XSSFRichTextString(textValue);
                cell.setCellValue(ri);
            }
        }
    }


    /**
     * 生成zip压缩文件
     */
    public static void fileToZip() {
        try {
            String zipFileName = "aaa.zip";
            //构建写入 aaa.zip
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
            for (int i = 0; i < 3; i++) {
                //todo 模拟拿到3个文件的输入流 可以调远程接口
                InputStream inputStream = new ByteArrayInputStream(new String(i + "").getBytes());
                out.putNextEntry(new ZipEntry("" + i));
                byte[] buffer = new byte[1024];
                int dataSize;
                while ((dataSize = inputStream.read(buffer)) > 0) {
                    out.write(buffer, 0, dataSize);
                }
            }
            //写完数据需要关闭流
            out.flush();
            out.close();

            //构建aaa.zip文件的输入流
            File fileZip = new File(zipFileName);
            FileInputStream fileInputStream = new FileInputStream(fileZip);
            BufferedInputStream bis = new BufferedInputStream(fileInputStream);

            //文件输入流中读取文件并写入到输出流byteArrayOutputStream
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            try {
                byte[] buffer = new byte[2048];
                int bytesRead;
                while ((bytesRead = bis.read(buffer)) != -1) {
                    // 处理读取到的bytesRead个字节数据
                    byteArrayOutputStream.write(buffer, 0, bytesRead);
                }
            } finally {
                byteArrayOutputStream.close();
                fileInputStream.close();
            }

            //删除文件
            boolean delete = fileZip.delete();
            System.out.println(delete);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
    }

    public static void main(String[] args) {
        fileToZip();
    }
}
